﻿using System.Collections.Generic;

namespace Godot.core
{
    using SysBindingFlags = System.Reflection.BindingFlags;
    using SysMethodInfo = System.Reflection.MethodInfo;

    public partial class ResourceImportMetadata : Reference
    {
        public class Source
        {
            public string path;
            public string md5;
        }

        
        public ResourceImportMetadata()
        {
            _sources = new List<Source>();
        }

        protected virtual bool _use_builtin_scrip()
        {
            return false;
        }

        protected List<string> _get_options() 
        {
	        List<string> option_names = new List<string>();	        
            foreach(KeyValuePair<string, Variant> E in _options)
            {
		        option_names.Add(E.Key);
	        }
	        return option_names;
        }

        public void set_editor(string p_editor)
        {
            _editor = p_editor;
        }

        public string get_editor()
        {
            return _editor;
        }

        public void add_source(string p_path, string p_md5 = "")
        {
            Source s = new Source() ;
            s.md5 = p_md5;
            s.path = p_path;
            _sources.Add(s);
        }

        public string get_source_path(int p_idx)
        {
            if(p_idx >= _sources.Count) return "";
            return _sources[p_idx].path;
        }

        public string get_source_md5(int p_idx)
        {
	        if(p_idx >= _sources.Count) return "";
	        return _sources[p_idx].md5;
        }

        public void set_source_md5(int p_idx, string p_md5)
        {
	        if(p_idx >= _sources.Count) return;
            _sources[p_idx].md5 = "";
        }

        public void remove_source(int p_idx)
        {
	        if(p_idx >= _sources.Count) return;
	        _sources.RemoveAt(p_idx);
        }

        public int get_source_count()
        {
	        return _sources.Count;
        }

        public void set_option(string p_key, Variant p_value) 
        {
	        if (p_value.type == Variant.Type.NIL) 
            {
		        _options.Remove(p_key);
		        return;
	        }

	        if(p_value.type == Variant.Type.OBJECT) return;
	        if(p_value.type == Variant.Type.RID) return;

	        _options[p_key] = p_value;
        }

        public Variant get_option(string p_key) 
        {
	        //if (!_options.ContainsKey(p_key))
		    //    print_line(p_key);
	        if(!_options.ContainsKey(p_key))
                return new Variant();
	        return _options[p_key];
        }

        protected static new void _bind_methods()
        {
            ObjectTypeDB.bind_method(_MD("set_editor","name"), typeof(ResourceImportMetadata).GetMethod("set_editor"));
            ObjectTypeDB.bind_method(_MD("get_editor"),typeof(ResourceImportMetadata).GetMethod("get_editor"));
            ObjectTypeDB.bind_method(_MD("add_source","path","md5"), typeof(ResourceImportMetadata).GetMethod("add_source"));
            ObjectTypeDB.bind_method(_MD("get_source_path","idx"),typeof(ResourceImportMetadata).GetMethod("get_source_path"));
            ObjectTypeDB.bind_method(_MD("get_source_md5","idx"),typeof(ResourceImportMetadata).GetMethod("get_source_md5"));
            ObjectTypeDB.bind_method(_MD("remove_source","idx"),typeof(ResourceImportMetadata).GetMethod("remove_source"));
            ObjectTypeDB.bind_method(_MD("get_source_count"),typeof(ResourceImportMetadata).GetMethod("get_source_count"));
            ObjectTypeDB.bind_method(_MD("set_option","key","value"),typeof(ResourceImportMetadata).GetMethod("set_option"));
            ObjectTypeDB.bind_method(_MD("get_option","key"),typeof(ResourceImportMetadata).GetMethod("get_option"));
            ObjectTypeDB.bind_method(_MD("get_options"),typeof(ResourceImportMetadata).GetMethod("_get_options", Misc.BindingFlags_Greedy));
        }

        protected string _editor;
        protected List<Source> _sources; 
        protected Dictionary<string, Variant> _options;
    }

    public partial class ResourceImportMetadata
    {
        #region OBJ_TYPE( ResourceImportMetadata, Reference )
        public override string get_type() { return "ResourceImportMetadata"; }

        public override string get_save_type() { return get_type(); } //type stored when saving

        public override StringName get_type_name() { return (StringName)get_type_static(); }

        public override bool is_type(string p_type) { return (p_type == "ResourceImportMetadata") ? true : base.is_type(p_type); }

        protected override void _initialize_typev() { initialize_type(); }

        protected override bool _setv(StringName p_name, Variant p_property)
        {
            if (base._setv(p_name, p_property))
                return true;

            if (typeof(ResourceImportMetadata).GetMethod("_set") != typeof(Reference).GetMethod("_set"))
            {
                return _set(p_name, p_property);
            }

            return false;
        }

        protected override bool _getv(StringName p_name, ref Variant r_property)
        {
            if (typeof(ResourceImportMetadata).GetMethod("_get") != typeof(Reference).GetMethod("_get"))
            {
                if (_get(p_name, ref r_property))
                    return true;
            }

            return base._getv(p_name, ref r_property);
        }

        protected override void _get_property_listv(ref List<PropertyInfo> p_list, bool p_reversed)
        {
            if (!p_reversed)
            {
                base._get_property_listv(ref p_list, p_reversed);
            }

            p_list.Add(new PropertyInfo(Variant.Type.NIL, get_type_static(), PropertyHint.PROPERTY_HINT_NONE, "", (int)PropertyUsageFlags.PROPERTY_USAGE_CATEGORY));

            if (!_is_gpl_reversed())
                ObjectTypeDB.get_property_list("ResourceImportMetadata", ref p_list, true);

            if (typeof(ResourceImportMetadata).GetMethod("_get_property_list") != typeof(Reference).GetMethod("_get_property_list"))
            {
                _get_property_list(ref p_list);
            }

            if (_is_gpl_reversed())
                ObjectTypeDB.get_property_list("ResourceImportMetadata", ref p_list, true);

            if (p_reversed)
            {
                base._get_property_listv(ref p_list, p_reversed);
            }
        }

        protected override void _notificationv(int p_notification, bool p_reversed)
        {
            if (!p_reversed)
                base._notificationv(p_notification, p_reversed);

            if (typeof(ResourceImportMetadata).GetMethod("_notification") != typeof(Reference).GetMethod("_notification"))
            {
                _notification(p_notification);
            }

            if (p_reversed)
                base._notificationv(p_notification, p_reversed);
        }

        public static new string get_type_static() { return "ResourceImportMetadata"; }

        public static new string get_parent_type_static() { return Reference.get_type_static(); }

        public static new void get_inheritance_list_static(ref List<string> r_inheritance_list)
        {
            Reference.get_inheritance_list_static(ref r_inheritance_list);
            r_inheritance_list.Add(get_type_static());
        }

        public static new string get_category_static()
        {
            string category = Reference.get_category_static();
            if (typeof(ResourceImportMetadata).GetMethod("_get_category") != typeof(Reference).GetMethod("_get_category"))
            {
                if (category != "")
                    category += "/";
                category += _get_category();
            }
            return category;
        }

        public static new string inherits_static() { return "Reference"; }

        public static new void get_valid_parents_static(ref List<string> p_parents)
        {
            if (typeof(ResourceImportMetadata).GetMethod("_get_valid_parents_static") != typeof(Reference).GetMethod("_get_valid_parents_static"))
            {
                ResourceImportMetadata._get_valid_parents_static(ref p_parents);
            }

            Reference.get_valid_parents_static(ref p_parents);
        }

        public static new void initialize_type()
        {
            if (__initialized)
                return;
            Reference.initialize_type();
            ObjectTypeDB._add_type<ResourceImportMetadata>();

            SysMethodInfo cls_bind = typeof(ResourceImportMetadata).GetMethod("_bind_methods", Misc.BindingFlags_Greedy);
            SysMethodInfo par_bind = typeof(Reference).GetMethod("_bind_methods", Misc.BindingFlags_Greedy);
            if (cls_bind != par_bind)
                cls_bind.Invoke(null, null);
            __initialized = true;
        }

        private static bool __initialized = false;
        #endregion
    }
}
